package com.tuomaxu.factory;

import com.tuomaxu.annotation.Autowired;
import com.tuomaxu.annotation.Component;
import com.tuomaxu.annotation.Qualifier;
import com.tuomaxu.utils.ScannerPackageUtils;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BeanFactory {
    private static Map<String,Object> map = new HashMap<>();

    static {
        //1,扫描所有类
        List<String> classNameList = scannerPackage();
        //2，如果有注解的类，创建对象
        createComponentObjects(classNameList);
        //3，扫描Auto注解字段，注入依赖
        autowiredProcess();
    }

    public static Object getBean(String id){
        return map.get(id);
    }

    private static List<String> scannerPackage(){

        return ScannerPackageUtils.scanner("com.tuomaxu");
    }

    private static void createComponentObjects(List<String> classNameList){
        try {
            for (String className : classNameList) {
                Class<?> aClass = Class.forName(className);
                if(aClass.isAnnotationPresent(Component.class)){
                    Object o = aClass.newInstance();
                    //id默认为全限定类名，如果Component中value有值，则使用该值
                    Component annotation = aClass.getAnnotation(Component.class);
                    String id = annotation.value().equals("")?className:annotation.value();
                    map.put(id,o);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void autowiredProcess() {
        try {
            for(String key : map.keySet()){
                //1，获取对象
                Object o = map.get(key);
                //2，获取对象字段
                Field[] declaredFields = o.getClass().getDeclaredFields();
                for (Field field : declaredFields) {
                    if(field.isAnnotationPresent(Autowired.class)){
                        field.setAccessible(true);

                        String id = field.getType().getName();
                        if(field.isAnnotationPresent(Qualifier.class)){
                            Qualifier qualifier = field.getAnnotation(Qualifier.class);
                            id = qualifier.value();
                        }
                        //通过id从map中获取ref对象
                        Object ref = map.get(id);
                        field.set(o,ref);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
